home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Graphics / sKulpt / skulpt-src / win-src / File-Sculpt.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-26  |  13.2 KB  |  361 lines

  1. #define STRICT
  2.  
  3. // Includes standard Windows
  4. #include <windows.h>
  5. #include <windowsx.h>
  6. #include <time.h>
  7. #include <stdlib.h>
  8. #include <malloc.h>
  9. #include <memory.h>
  10. #include <stdio.h>
  11. #include <math.h>
  12. #include <io.h>
  13.  
  14. // Includes D3D
  15. #define  D3D_OVERLOADS
  16. #include <ddraw.h>
  17. #include <d3d.h>
  18. #include <d3dx.h>
  19.  
  20. // Includes utilitaires D3D
  21. #include "d3dmath.h"
  22. #include "d3dutil.h"
  23. #include "D3DEnum.h"
  24.  
  25. // Ids Resources
  26. #include "resource.h"
  27.  
  28. // Constantes
  29. #include "const.h"
  30.  
  31. // Types
  32. #include "types.h"
  33.  
  34. // Variables globales projet
  35. #include "vars.h"
  36.  
  37. // Prototypes fonctions autres modules
  38. #include "proto.h"
  39.  
  40. // Macros
  41. #include "macros.h"
  42.  
  43. void vLoadSculpt(void)
  44. {
  45.     evertex *saVertices = NULL;
  46.     eface *saFaces = NULL;
  47.     elamp *saLamps = NULL;
  48.     world saWorld;
  49.     int *iVertIndexMap = NULL, *iLampIndexMap = NULL;
  50.     observer saObserver;
  51.     BOOL bObs = FALSE;
  52.     int iNumVertex = 0, iNumFace = 0, iNumLamps = 0;
  53.     char cBuffer[13];
  54.     long iX, iY;
  55.     float fEnvXmin = 2000000000., fEnvXmax = -2000000000., fEnvSize;
  56.     float fEnvYmin = 2000000000., fEnvYmax = -2000000000.;
  57.     float fEnvZmin = 2000000000., fEnvZmax = -2000000000.;
  58.     HANDLE hFile;
  59.     static TCHAR sInitialDir[512] = "";
  60.     static TCHAR sFileName[512];
  61.     TCHAR sCurrentName[512] = "*.scene";
  62.     OFSTRUCT ReOpenBuff;
  63.     DWORD dwNBytesRead;
  64.  
  65.     // Récupérer le directory courant
  66.     GetCurrentDirectory(sizeof(sInitialDir), sInitialDir);
  67.  
  68.     // Préparer une structure OPENFILENAME
  69.     OPENFILENAME sOFName = { sizeof(OPENFILENAME), NULL, NULL,
  70.                          "Fichiers Scènes (*.scene)\0*.scene\0\0",
  71.                          NULL, 0, 1, sCurrentName, 512, sFileName, 512,
  72.                          sInitialDir, "Ouvrir un fichier scène", OFN_FILEMUSTEXIST, 0, 1,
  73.                          ".scene", 0, NULL, NULL };
  74.  
  75.     // Choisir un fichier
  76.     if(!GetOpenFileName(&sOFName))
  77.         return;
  78.  
  79.     // Stocker le nom du directory pour le prochain appel
  80.     strcpy(sInitialDir, sCurrentName);
  81.     strstr(sInitialDir, sFileName)[0] = '\0';
  82.  
  83.     // Ouvrir le fichier en lecture
  84.     if ((HANDLE) HFILE_ERROR == (hFile = (HANDLE) OpenFile(sFileName, &ReOpenBuff, OF_READ)))
  85.         return;
  86.  
  87.     vTrace("*** Fichier scène : %s", sFileName);
  88.         
  89.     // Vérifier la structure d'entête Sculpt 3D
  90.     ReadFile(hFile, cBuffer, 12, &dwNBytesRead, NULL);
  91.     if (strncmp((char *) cBuffer, "FORM", 4) || strncmp((char *) cBuffer + 8, "SC3D", 4))
  92.     {
  93.         vTrace("*** E0024 : En-tête fichier scène incorrect");
  94.         goto _Fin;
  95.     }
  96.  
  97.     // Parcourir le fichier en décodant les chunks au fur et à mesure
  98.     while ((ReadFile(hFile, cBuffer, 4, &dwNBytesRead, NULL)) && (dwNBytesRead == 4))
  99.     {
  100.         vTrace("Chunk : %4s", cBuffer);
  101.  
  102.         if (!strncmp((char *) cBuffer, "VERT", 4))    // Sommets
  103.         {
  104.             // Charger le nombre de vertex
  105.             ReadFile(hFile, &iX, 4, &dwNBytesRead, NULL);
  106.             iNumVertex = swapl(iX) / sizeof(evertex);
  107.             vTrace("Nombre de sommets : %ld", iNumVertex);
  108.  
  109.             // Allouer une structure temporaire pour les vertex Sculpt, avec leurs coordonnées INT
  110.             saVertices = (evertex *) malloc(iNumVertex * sizeof(evertex));
  111.             if (!saVertices)
  112.             {
  113.                 vTrace("*** E0025 : Erreur malloc saVertices");
  114.                 goto _Fin;
  115.             }
  116.  
  117.             // Allouer une structure d'index pour les vertex
  118.             // (les vertex sont lus dans l'ordre dans le fichier, mais la fonction
  119.             // iMakeVertex les range comme elle peut dans le tableau global de vertex,
  120.             // donc pour réindexer les triangles et normaliser les coordonnées lues
  121.             // il faut conserver la trace des permutations)
  122.             iVertIndexMap = (int *) malloc(iNumVertex * sizeof(int));
  123.             if (!iVertIndexMap)
  124.             {
  125.                 vTrace("*** E0026 : Erreur malloc iVertIndexMap");
  126.                 goto _Fin;
  127.             }
  128.  
  129.             // Lire la structure de vertex sculpt du fichier dans la structure allouée ci-dessus
  130.             ReadFile(hFile, saVertices, iNumVertex * sizeof(evertex), &dwNBytesRead, NULL);
  131.  
  132.             // Pour chaque vertex sculpt (coordonnées INT),
  133.             // - convertir les coordonnées en float
  134.             // - créer un vecteur temporaire et y copier les coordonnées converties en float
  135.             // - demander à la fonction iMakeVertex de stocker le point défini par le vecteur temporaire
  136.             // - mémoriser dans la table d'index où la fonction iMakeVertex a rangé le point
  137.             for (int iVertex = 0 ; iVertex < iNumVertex ; iVertex++)
  138.             {
  139.                 iX = saVertices[iVertex].pos[0] = swapl(saVertices[iVertex].pos[0]);
  140.                 if (fEnvXmin > (float) iX) fEnvXmin = (float) iX; if (fEnvXmax < (float) iX) fEnvXmax = (float) iX;
  141.                 
  142.                 iX = saVertices[iVertex].pos[1] = swapl(saVertices[iVertex].pos[1]);
  143.                 if (fEnvYmin > (float) iX) fEnvYmin = (float) iX; if (fEnvYmax < (float) iX) fEnvYmax = (float) iX;
  144.                 
  145.                 iX = saVertices[iVertex].pos[2] = swapl(saVertices[iVertex].pos[2]);
  146.                 if (fEnvZmin > (float) iX) fEnvZmin = (float) iX; if (fEnvZmax < (float) iX) fEnvZmax = (float) iX;
  147.                 
  148.                 iVertIndexMap[iVertex] = iMakeVertex(
  149.                     D3DVECTOR(
  150.                         (float) saVertices[iVertex].pos[0],
  151.                         (float) saVertices[iVertex].pos[1],
  152.                         (float) saVertices[iVertex].pos[2]),
  153.                     XDC_FORCENEW);
  154.             }
  155.             continue;
  156.         }
  157.  
  158.         if (!strncmp((char *) cBuffer, "LAMP", 4))    // Sommets
  159.         {
  160.             // Charger le nombre de lampes
  161.             ReadFile(hFile, &iX, 4, &dwNBytesRead, NULL);
  162.             iNumLamps = swapl(iX) / sizeof(elamp);
  163.             vTrace("Nombre de lampes : %ld", iNumLamps);
  164.  
  165.             // Allouer une structure temporaire pour les vertex Sculpt, avec leurs coordonnées INT
  166.             saLamps = (elamp *) malloc(iNumLamps * sizeof(elamp));
  167.             if (!saLamps)
  168.             {
  169.                 vTrace("*** E0027 : Erreur malloc saLamps");
  170.                 goto _Fin;
  171.             }
  172.  
  173.             // Allouer une structure d'index pour les lampes
  174.             // (les vertex sont lus dans l'ordre dans le fichier, mais la fonction
  175.             // iMakeLamp les range comme elle peut dans le tableau global de lampes,
  176.             // donc pour normaliser les coordonnées des lampes il faut conserver la trace des rangements)
  177.             iLampIndexMap = (int *) malloc(iNumLamps * sizeof(int));
  178.             if (!iLampIndexMap)
  179.             {
  180.                 vTrace("*** E0028 : Erreur malloc iLampIndexMap");
  181.                 goto _Fin;
  182.             }
  183.  
  184.             // Lire la structure de vertex sculpt du fichier dans la structure allouée ci-dessus
  185.             ReadFile(hFile, saLamps, iNumLamps * sizeof(elamp), &dwNBytesRead, NULL);
  186.  
  187.             // Pour chaque lampe sculpt (coordonnées INT),
  188.             // - convertir les coordonnées en float
  189.             // - créer un vecteur temporaire et y copier les coordonnées converties en float
  190.             // - demander à la fonction iMakeLamp de stocker le point défini par le vecteur temporaire
  191.             // - mémoriser dans la table d'index où la fonction iMakeLamp a rangé le point
  192.             for (int iLamp = 0 ; iLamp < iNumLamps ; iLamp++)
  193.             {
  194.                 saLamps[iLamp].pos[0] = swapl(saLamps[iLamp].pos[0]);
  195.                 saLamps[iLamp].pos[1] = swapl(saLamps[iLamp].pos[1]);
  196.                 saLamps[iLamp].pos[2] = swapl(saLamps[iLamp].pos[2]);
  197.                 
  198.                 saLamps[iLamp].brightness = swapl(saLamps[iLamp].brightness);
  199.                 
  200.                 vTrace("Lampe %d (%d, %d, %d). Bright %d, R %d G %d B %d", iLamp,
  201.                     saLamps[iLamp].pos[0], saLamps[iLamp].pos[1], saLamps[iLamp].pos[2],
  202.                     saLamps[iLamp].brightness,
  203.                     saLamps[iLamp].color[0], saLamps[iLamp].color[1], saLamps[iLamp].color[2]);
  204.  
  205.                 D3DCOLORVALUE   dcvDiffuse    = {saLamps[iLamp].color[0]/255.f, saLamps[iLamp].color[1]/255.f, saLamps[iLamp].color[2]/255.f, 0.f};
  206.                 D3DCOLORVALUE   dcvSpecular    = {saLamps[iLamp].color[0]/255.f, saLamps[iLamp].color[1]/255.f, saLamps[iLamp].color[2]/255.f, 0.f};
  207.                 D3DCOLORVALUE   dcvAmbient    = {saLamps[iLamp].color[0]/255.f, saLamps[iLamp].color[1]/255.f, saLamps[iLamp].color[2]/255.f, 0.f};
  208.  
  209.                 iLampIndexMap[iLamp] = iMakeLamp(
  210.                         D3DLIGHT_POINT,
  211.                         dcvDiffuse,
  212.                         dcvSpecular,
  213.                         dcvAmbient,
  214.                         D3DVECTOR((float) saLamps[iLamp].pos[0], (float) saLamps[iLamp].pos[1], (float) saLamps[iLamp].pos[2]),
  215.                         D3DVECTOR(0.f, 0.f, 0.f),
  216.                         D3DLIGHT_RANGE_MAX,
  217.                         0.f,
  218.                         0.f,
  219.                         0.5f,
  220.                         0.f,
  221.                         0.f,
  222.                         0.f);
  223.             }
  224.             continue;
  225.         }
  226.  
  227.         if (!strncmp((char *) cBuffer, "FACE", 4))
  228.         {
  229.             // Charger le nombre de faces
  230.             ReadFile(hFile, &iX, 4, &dwNBytesRead, NULL);
  231.             iNumFace = swapl(iX) / sizeof(eface);
  232.             vTrace("Nombre de faces : %ld", iNumFace);
  233.  
  234.             // Allouer une structure temporaire pour ranger les faces Sculpt 3D
  235.             saFaces = (eface *) malloc(iNumFace * sizeof(eface));    
  236.             if (!saFaces)
  237.             {
  238.                 vTrace("*** E0029 : Erreur malloc saFaces");
  239.                 goto _Fin;
  240.             }
  241.  
  242.             // Lire les faces Sculpt du fichier
  243.             ReadFile(hFile, saFaces, iNumFace * sizeof(eface), &dwNBytesRead, NULL);
  244.  
  245.             // Pour chaque face : créer un triangle avec les sommets (index mappés)
  246.             for (int iFace = 0 ; iFace < iNumFace ; iFace++)
  247.             {
  248.                 saFaces[iFace].evertexi[0] = swapl(saFaces[iFace].evertexi[0]);
  249.                 saFaces[iFace].evertexi[1] = swapl(saFaces[iFace].evertexi[1]);
  250.                 saFaces[iFace].evertexi[2] = swapl(saFaces[iFace].evertexi[2]);
  251.  
  252.                 iMakeTriangle(iVertIndexMap[saFaces[iFace].evertexi[0]],
  253.                           iVertIndexMap[saFaces[iFace].evertexi[1]],
  254.                           iVertIndexMap[saFaces[iFace].evertexi[2]],
  255.                           saFaces[iFace].color[0], saFaces[iFace].color[1], saFaces[iFace].color[2]);
  256.             }
  257.             continue;
  258.         }
  259.  
  260.         if (!strncmp((char *) cBuffer, "OBSV", 4))
  261.         {
  262.             bObs = TRUE;
  263.  
  264.             // Sauter la taille du chunk
  265.             ReadFile(hFile, &iX, sizeof(iX), &dwNBytesRead, NULL);
  266.  
  267.             // Charger la structure observer
  268.             ReadFile(hFile, &saObserver, sizeof(saObserver), &dwNBytesRead, NULL);
  269.  
  270.             // Mettre à jour les coordonnées de l'observateur et de la cible
  271.             saObserver.robspos[0] = swapl(saObserver.robspos[0]);
  272.             saObserver.robspos[1] = swapl(saObserver.robspos[1]);
  273.             saObserver.robspos[2] = swapl(saObserver.robspos[2]);
  274.  
  275.             saObserver.rtarget[0] = swapl(saObserver.rtarget[0]);
  276.             saObserver.rtarget[1] = swapl(saObserver.rtarget[1]);
  277.             saObserver.rtarget[2] = swapl(saObserver.rtarget[2]);
  278.  
  279.             continue;
  280.         }
  281.  
  282.         if (!strncmp((char *) cBuffer, "WRLD", 4))
  283.         {
  284.             bObs = TRUE;
  285.  
  286.             // Sauter la taille du chunk
  287.             ReadFile(hFile, &iX, sizeof(iX), &dwNBytesRead, NULL);
  288.  
  289.             // Charger la structure observer
  290.             ReadFile(hFile, &saWorld, sizeof(saWorld), &dwNBytesRead, NULL);
  291.  
  292.             // Mettre à jour l'éclairage ambiant et la couleur du fond
  293.             cAmbient = saWorld.backbright[0] + (saWorld.backbright[1] << 8) + (saWorld.backbright[2] << 16);
  294.             cBack = saWorld.skycol1[0] + (saWorld.skycol1[1] << 8) + (saWorld.skycol1[2] << 16);
  295.  
  296.             continue;
  297.         }
  298.  
  299.         // Chunk non traité.
  300.         ReadFile(hFile, &iX, 4, &dwNBytesRead, NULL);
  301.         vTrace("Skip %d octets", iY = swapl(iX));
  302.         SetFilePointer(hFile, iY, NULL, FILE_CURRENT);
  303.     }
  304.  
  305. _Fin:
  306.  
  307.     // Fermer le fichier
  308.     CloseHandle(hFile);
  309.  
  310.     // Calculer la plus grande dimension de la scène
  311.     fEnvSize = fEnvXmax - fEnvXmin;
  312.     if (fEnvYmax - fEnvYmin > fEnvSize) fEnvSize = fEnvYmax - fEnvYmin;
  313.     if (fEnvZmax - fEnvZmin > fEnvSize)    fEnvSize = fEnvZmax - fEnvZmin;
  314.  
  315.     // Normaliser les coordonnées de tous les points lus
  316.     for (int iVertex = 0 ; iVertex < iNumVertex ; iVertex++)
  317.     {
  318.         Vertices[iVertIndexMap[iVertex]].vPoint.x = ((Vertices[iVertIndexMap[iVertex]].vPoint.x - fEnvXmin - (fEnvXmax - fEnvXmin) / 2.f) * 8.f / fEnvSize);
  319.         Vertices[iVertIndexMap[iVertex]].vPoint.y = ((Vertices[iVertIndexMap[iVertex]].vPoint.y - fEnvYmin - (fEnvYmax - fEnvYmin) / 2.f) * 8.f / fEnvSize);
  320.         Vertices[iVertIndexMap[iVertex]].vPoint.z = ((Vertices[iVertIndexMap[iVertex]].vPoint.z - fEnvZmin - (fEnvZmax - fEnvZmin) / 2.f) * 8.f / fEnvSize);
  321.     }
  322.  
  323.     // Normaliser les coordonnées de toutes les lampes
  324.     for (int iLamp = 0 ; iLamp < iNumLamps ; iLamp++)
  325.     {
  326.         Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.x = ((Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.x - fEnvXmin - (fEnvXmax - fEnvXmin) / 2.f) * 8.f / fEnvSize);
  327.         Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.y = ((Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.y - fEnvYmin - (fEnvYmax - fEnvYmin) / 2.f) * 8.f / fEnvSize);
  328.         Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.z = ((Lampes[iLampIndexMap[iLamp]].lLamp.dvPosition.z - fEnvZmin - (fEnvZmax - fEnvZmin) / 2.f) * 8.f / fEnvSize);
  329.         bUpdateLamp(iLampIndexMap[iLamp]);
  330.     }
  331.  
  332.     // Forcer le recalcul des sommets de chaque triangle (car on a changé les points)
  333.     for (int iTriangle = 0 ; iTriangle <= iTriaLastUsed ; iTriangle++)
  334.         bUpdateD3DTri(iTriangle);
  335.  
  336.     // Si on a lu les coordonnées de l'observateur et de la target alors les positionner
  337.     if (bObs)
  338.     {
  339.         Observer.x = ((float) saObserver.robspos[0] - fEnvXmin - (fEnvXmax - fEnvXmin) / 2.f) * 8.f / fEnvSize;
  340.         Observer.y = ((float) saObserver.robspos[1] - fEnvYmin - (fEnvYmax - fEnvYmin) / 2.f) * 8.f / fEnvSize;
  341.         Observer.z = ((float) saObserver.robspos[2] - fEnvZmin - (fEnvZmax - fEnvZmin) / 2.f) * 8.f / fEnvSize;
  342.         Target.x = ((float) saObserver.rtarget[0] - fEnvXmin - (fEnvXmax - fEnvXmin) / 2.f) * 8.f / fEnvSize;
  343.         Target.y = ((float) saObserver.rtarget[1] - fEnvYmin - (fEnvYmax - fEnvYmin) / 2.f) * 8.f / fEnvSize;
  344.         Target.z = ((float) saObserver.rtarget[2] - fEnvZmin - (fEnvZmax - fEnvZmin) / 2.f) * 8.f / fEnvSize;
  345.         D3DUtil_SetViewMatrix(matView,
  346.               Observer,    // From
  347.               Target,    // To
  348.               D3DVECTOR(0.f, 0.f, 0.f));
  349.     }
  350.  
  351.     // Libérer les allocations mémoire
  352.     if (saFaces) { free(saFaces); saFaces = NULL; }
  353.     if (saVertices) { free(saVertices); saVertices = NULL; }
  354.     if (iVertIndexMap) { free(iVertIndexMap); iVertIndexMap = NULL; }
  355.     if (iLampIndexMap) { free(iLampIndexMap); iLampIndexMap = NULL; }
  356. }
  357.  
  358. void vSaveSculpt(void)
  359. {
  360. }
  361.